<template>
  <main class="main-container" v-loading="isLoading" :element-loading-text="loadingText">
    <div class="main-content">
      <div class="search-bar">
        <div>
          <el-text>项目名称：</el-text>
          <el-select
            v-model="currentProjectName"
            class="project-select"
            filterable
            placeholder="请选择要查询部件的项目"
          >
            <el-option
              v-for="projectInfo in projects"
              :key="projectInfo.id"
              :label="projectInfo.projectName"
              :value="projectInfo.projectName"
            ></el-option>
          </el-select>
        </div>
        <div>
          <el-button
            type="primary"
            :icon="CirclePlusFilled"
            :disabled="disableOperationButton"
            @click="showAddPartDialog = true"
            >新增</el-button
          >
        </div>
      </div>
      <el-divider />
      <div class="table-content">
        <el-table :data="parts" class="table">
          <el-table-column prop="partName" label="部件名称" />
          <el-table-column prop="partOwnerName" label="所属部件" />
          <el-table-column prop="deviceId" label="设备节点" />
          <el-table-column fixed="right" label="操作" width="120">
            <template #default="scope">
              <el-button link type="primary" size="small" @click="onDeletePartAsync(scope.$index)">
                删除
              </el-button>
            </template>
          </el-table-column>
        </el-table>
      </div>
    </div>
    <el-dialog
      v-model="showAddPartDialog"
      title="添加新部件"
      width="400"
      :close-on-click-modal="false"
      draggable
      :before-close="onDialogBeforeClose"
      @open="onOpenAddPartDialogAsync"
    >
      <div v-loading="dialogIsLoading" element-loading-text="正在添加新部件...">
        <div>
          <el-text>部件名称：</el-text>
          <el-input
            style="margin-top: 4px"
            maxlength="40"
            type="text"
            v-model="partName"
          ></el-input>
        </div>
        <div>
          <el-text>所属部件名称：</el-text>
          <el-select v-model="partOwnerName" filterable clearable>
            <el-option
              v-for="item in parts"
              :key="item.id"
              :label="item.partName"
              :value="item.partName"
            />
          </el-select>
        </div>
        <div style="margin-top: 10px">
          <el-text>设备节点ID：</el-text>
          <el-select v-model="nodeId" filterable clearable placeholder="请选择设备节点 ID">
            <el-option v-for="item in nodeIds" :key="item" :label="item" :value="item" />
          </el-select>
        </div>

        <div style="display: flex; justify-content: center; margin-top: 20px">
          <el-button type="primary" @click="onInsertPatAsync">添加</el-button>
        </div>
      </div>
    </el-dialog>
  </main>
</template>

<script lang="ts" setup>
import { computed, onMounted, ref, watch } from 'vue';
import { Project } from './Project';
import type { ProjectInfo } from '@/types/ProjectInfo';
import { sleepAsync } from '@/utils/test-api';
import { ElMessage } from 'element-plus';
import { deletePartAsync, getPartsAsync, insertPartAsync } from '@/utils/project-api';
import { Part } from '@/types/Part';
import { PartInfo } from '@/types/PartInfo';
import { CirclePlusFilled } from '@element-plus/icons-vue';
import { getNodeIdsAsync } from '@/utils/device-server-client';
import { showDeleteMessageBoxAsync } from '@/utils/message-box';

const project = new Project();
const currentProjectName = ref('');
const loadingText = ref('正在加载项目列表...');
const isLoading = ref(false);
const projects = ref<ProjectInfo[]>([]);
const parts = ref<PartInfo[]>([]);
const dialogIsLoading = ref(false);
const pageIndex = ref(0);
const pageSize = 50;

const partName = ref('');
const partOwnerName = ref('');
const nodeId = ref('');
const nodeIds = ref<string[] | null>(null);
const warningTaskName = '';
const currentValueTaskName = '';
const stopValueTaskName = '';
const warningValueTaskName = '';

function resetProps() {
  partName.value = '';
  partOwnerName.value = '';
  nodeId.value = '';
}

const disableOperationButton = computed(() => {
  return (
    currentProjectName.value == null ||
    currentProjectName.value == '' ||
    currentProjectName.value == undefined
  );
});
const showAddPartDialog = ref(false);

function openDialogLoading() {
  dialogIsLoading.value = true;
}

function closeDialogLoading() {
  dialogIsLoading.value = false;
}

// 打开添加部件对话框页面时，初始化设备节点列表
async function onOpenAddPartDialogAsync() {
  if (nodeIds.value != null) {
    return;
  }
  try {
    openDialogLoading();
    const result = await getNodeIdsAsync();
    if (result.isSuccess) {
      nodeIds.value = result.result ?? [];
    } else {
      throw result.message;
    }
  } catch (err) {
    const message = err as string;
    if (message != null) {
      ElMessage.warning(message);
    } else {
      console.error(err);
      ElMessage.error('获取设备ID列表错误！');
    }
  } finally {
    closeDialogLoading();
  }
}

function openLoading() {
  // 如果对话框 loading 了，则不加载页面 loading
  if (!dialogIsLoading.value) isLoading.value = true;
}

function closeLoading() {
  isLoading.value = false;
}

watch(currentProjectName, async (newValue) => {
  if (newValue != null && newValue != '' && newValue != undefined) {
    await updatePartsAsync();
  }
});
onMounted(() => {
  updateProjectsAsync();
});

// 更新项目列表
async function updateProjectsAsync() {
  loadingText.value = '正在加载项目列表...';
  try {
    openLoading();
    await sleepAsync(500);
    projects.value = await project.getAsync(pageIndex.value * pageSize, pageSize);
  } catch (err) {
    const message = err as string;
    if (message != null) {
      ElMessage.warning(message);
    } else {
      console.error(err);
      ElMessage.error('获取项目列表错误！');
    }
  } finally {
    closeLoading();
  }
}

// 更新部件列表
async function updatePartsAsync() {
  loadingText.value = '正在加载部件...';
  openLoading();
  try {
    const currentProject = projects.value.find(
      (item) => item.projectName == currentProjectName.value
    );
    await sleepAsync(500);
    const result = await getPartsAsync(currentProject!.id);
    if (result.isSuccess) {
      const partArray = result.result ?? [];
      parts.value = partArray.map((item) => {
        const partInfo: PartInfo = {
          ...item,
          partOwnerName:
            item.partOwnerId == null
              ? ''
              : partArray.find((partItem) => partItem.id == item.partOwnerId)?.partName ?? ''
        };
        return partInfo;
      });
    } else {
      throw result.message;
    }
  } catch (err) {
    const message = err as string;
    if (message != null) {
      ElMessage.warning(message);
    } else {
      console.error(err);
      ElMessage.error('获取部件列表错误！');
    }
  } finally {
    closeLoading();
  }
}

function onDialogBeforeClose(done: any) {
  if (dialogIsLoading.value) {
    ElMessage.info('正在添加新的部件...');
  }
  // 对话框正在加载时，不关闭对话框
  done(dialogIsLoading.value);
}

async function onInsertPatAsync() {
  const currentProject = projects.value.find(
    (item) => item.projectName == currentProjectName.value
  );
  const owner = parts.value.find((item) => item.partName == partOwnerName.value);

  try {
    openDialogLoading();
    await sleepAsync(500);
    await insertPartAsync({
      projectId: currentProject!.id,
      partName: partName.value,
      deviceId: nodeId.value,
      partOwnerId: owner?.id,
      warningTaskName: warningTaskName,
      currentValueTaskName: currentValueTaskName,
      warningValueTaskName: warningValueTaskName,
      stopValueTaskName: stopValueTaskName
    } as Part);
    await updatePartsAsync();
    resetProps();
    showAddPartDialog.value = false;
  } catch (err) {
    const message = err as string;
    if (message != null) {
      ElMessage.warning(message);
    } else {
      console.error(err);
      ElMessage.error('添加新部件错误！');
    }
  } finally {
    closeDialogLoading();
  }
}

async function onDeletePartAsync(index: number) {
  if (!(await showDeleteMessageBoxAsync())) {
    return;
  }
  const currentPartId = parts.value[index].id!;

  loadingText.value = '正在删除部件...';
  openLoading();
  await sleepAsync(500);

  try {
    await deletePartAsync(currentPartId);
    await updatePartsAsync();
  } catch (err) {
    const message = err as string;
    if (message != null) {
      ElMessage.warning(message);
    } else {
      console.error(err);
      ElMessage.error('删除部件错误！');
    }
  } finally {
    closeLoading();
  }
}
</script>

<style lang="scss" scoped>
:deep(.el-divider--horizontal) {
  margin: 15px 0px 0px 0px;
}

.main-container {
  height: 100%;
  width: 100%;
  padding: 0px 15px 15px 15px;

  .main-content {
    height: 100%;
    width: 100%;
    display: flex;
    flex-direction: column;
    overflow: hidden;

    .search-bar {
      display: flex;
      flex-direction: row;
      align-items: center;
      justify-content: space-between;

      .project-select {
        width: 240px;
        margin-left: 10px;
      }
    }

    .table-content {
      flex-grow: 1;
      overflow: hidden;
      .table {
        height: 100%;
      }
    }
  }
}
</style>